package com.aispeech.asr.comm.utils;

import org.apache.commons.lang3.StringUtils;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;

public class MetaUtils {
    private static final List<String> NUMBER_FIELDs = Arrays.asList("bg", "ed", "speaker");
    private static final List<String> EXTRA_FIELDs = Arrays.asList("emotion", "age", "gender");
    private static final List<String> SEGMENT_FIELDs = Arrays.asList("bg", "ed", "speaker", "onebest");

    public static List<Map<String, Object>> readLine(String path, List<String> fields, String speakerNumber, boolean useAux) throws IOException {
        return readLine(path, fields, -1, null, speakerNumber, useAux);
    }

    public static List<Map<String, Object>> readLine(String path, List<String> fields, int pos, String prefix, String speakerNumber, boolean useAux) throws IOException {
        List<Map<String, Object>> results = new ArrayList<>();
        boolean ignoreSpeakerInfo = "0".equals(speakerNumber);

        BufferedReader reader = new BufferedReader(new FileReader(path));
        String line;
        String value;
        String[] row;
        Map<String, Object> data;
        Map<String, Object> auxInfo;

        while ((line = reader.readLine()) != null) {
            if (!line.startsWith("#") && !line.startsWith("//")) {
                row = line.split(" ", fields.size());

                data = new HashMap<>();
                auxInfo = new HashMap<>();
                for (int idx_field = 0; idx_field < fields.size(); idx_field++) {
                    value = row[idx_field];

                    if ((idx_field == pos) && (StringUtils.isNotEmpty(prefix))) {
                        if (!value.startsWith("/")) {
                            value = prefix + value;
                        }
                    }

                    if ("onebest".equals(fields.get(idx_field))) {
                        String[] arr_rec = value.split("#\\*#\\*#", 2);
                        value = arr_rec[0];
                    } else if (ignoreSpeakerInfo && "speaker".equals(fields.get(idx_field))) {
                        continue;
                    } else if (NUMBER_FIELDs.contains(fields.get(idx_field))) {
                        data.put(fields.get(idx_field), Integer.valueOf(value));
                        continue;
                    } else if (EXTRA_FIELDs.contains(fields.get(idx_field))) {
                        auxInfo.put(fields.get(idx_field), value);
                        continue;
                    }

                    data.put(fields.get(idx_field), value);
                }

                if (useAux)
                    data.put("auxinfo", auxInfo);

                results.add(data);
            }

        }

        reader.close();

        return results;
    }

    public static List<Map<String, Object>> segment(String path) throws IOException {
        List<Map<String, Object>> results = new ArrayList<>();
        BufferedReader reader = new BufferedReader(new FileReader(path));
        String line;
        String value;
        String[] row;
        Map<String, Object> data;

        while ((line = reader.readLine()) != null) {
            if (!line.startsWith("#") && !line.startsWith("//")) {
                row = line.split(" ", SEGMENT_FIELDs.size());

                data = new HashMap<>();
                for (int idx_field = 0; idx_field < SEGMENT_FIELDs.size(); idx_field++) {
                    value = row[idx_field];

                    if (idx_field < 3) {
                        data.put(SEGMENT_FIELDs.get(idx_field), Integer.valueOf(value));
                    } else {
                        data.put(SEGMENT_FIELDs.get(idx_field), value.trim());
                    }
                }

                results.add(data);
            }

        }

        reader.close();

        return results;
    }

    public static int querySampleRateValue(Path infoFilePath) throws IOException {
        int sampleRates = 16000;

        List<String> lines = Files.readAllLines(infoFilePath);

        for (String line : lines) {
            if (line.startsWith("rate=")) {
                sampleRates = Integer.parseInt(line.substring(5));
                break;
            }
        }

        return sampleRates;
    }
}
